package com.yanqu.road.server.gameplayer.module.skin;

import com.yanqu.road.dao.impl.player.UserPatronsSkinBondDaoImpl;
import com.yanqu.road.entity.assistant.UserAssistantDecoration;
import com.yanqu.road.entity.config.beauty.BeautyInfo;
import com.yanqu.road.entity.config.goods.GoodsBagInfo;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.patrons.CombInfo;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.config.skill.SkillUpgradeInfo;
import com.yanqu.road.entity.config.skin.SkinInfo;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.LogManorSkinLvUp;
import com.yanqu.road.entity.log.LogSkinVolumePiecesGet;
import com.yanqu.road.entity.manor.ManorTechnologyData;
import com.yanqu.road.entity.player.*;
import com.yanqu.road.logic.bussiness.player.UserSkinBusiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.SkinPb;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.pb.skin.SkinProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.assistant.AssistantSkinModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.manor.ManorModule;
import com.yanqu.road.server.gameplayer.module.manor.ManorTechnologyModel;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.*;
import com.yanqu.road.server.gameplayer.module.resource.GoodsResourceModule;
import com.yanqu.road.server.manger.DataAnalyticsMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.server.manger.assistant.AssistantSkinMgr;
import com.yanqu.road.server.manger.config.*;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.manor.ManorMgr;
import com.yanqu.road.server.manger.system.CommonMgr;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import org.apache.mina.util.ConcurrentHashSet;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author wpj
 * @Date 2020/9/1
 */
public class SkinModule extends GeneralModule {

    Map<Integer, UserSkin> userSkinMap;

    Map<Integer, UserLTPMainRoleSkin> userLTPMainRoleSkinMap;

    Map<Integer, UserPatronsSkinBond> userPatronsSkinBondMap;

    public Map<Integer, UserSkin> getUserSkinMap() {
        return userSkinMap;
    }

    public Map<Integer, UserLTPMainRoleSkin> getUserLTPMainRoleSkinMap() {
        return userLTPMainRoleSkinMap;
    }

    public SkinModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        Map<Integer, UserSkin> tempUserSkinMap = UserSkinBusiness.getUserSkinMap(player.getUserId());
        try {
            //指定国内渠道屏蔽同时拥有美女103001和103209的,屏蔽103209
            //同时有皮肤109640和109643的屏蔽 103209的皮肤
            int channelId = ServerListMgr.getChannelId(GameServer.getInstance().getServerId());
            if (
                    channelId == 201 ||
                            channelId == 221 ||
                            channelId == 231 ||
                            channelId == 241 ||
                            channelId == 301 ||
                            channelId == 311 ||
                            channelId == 321) {
                if (tempUserSkinMap.containsKey(109640) && tempUserSkinMap.containsKey(109643)) {
                    SkinInfo skinInfo109640 = SkinMgr.getSkinInfo(109640);
                    SkinInfo skinInfo109643 = SkinMgr.getSkinInfo(109643);
                    if (skinInfo109643 != null && skinInfo109643.getBelongRole() == 103209) {
                        tempUserSkinMap.remove(skinInfo109643.getSkinId());
                    }
                    if (skinInfo109640 != null && skinInfo109640.getBelongRole() == 103209) {
                        tempUserSkinMap.remove(skinInfo109640.getSkinId());
                    }
                }
            }
        } catch (Exception e) {
            log.error(e);
        }
        userSkinMap = tempUserSkinMap;
        userLTPMainRoleSkinMap = UserSkinBusiness.getUserLTPMainRoleSkinMap(player.getUserId());
        userPatronsSkinBondMap = new UserPatronsSkinBondDaoImpl().getUserPatronsSkinBond(player.getUserId());
        return true;
    }

    @Override
    public boolean afterLoadData() {
        //修复技能错误信息
        for (UserSkin userSkin : userSkinMap.values()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
            checkPatronsSkinCombUnlock(userSkin, skinInfo, false);
        }

        try {//热更修复羁绊配错的数据
            for (UserPatronsSkinBond skinBond : userPatronsSkinBondMap.values()) {
                int combId = skinBond.getCombId();
                List<Integer> removeIdList = new ArrayList<>();
                for (Integer skinId : skinBond.getBondIdSet()) {
                    CombInfo combInfo = SkinMgr.getSkinBondCombInfoBySkinId(skinId);
                    if (null == combInfo || combInfo.getId() != combId) {
                        //皮肤羁绊错误修正
                        removeIdList.add(skinId);
                    }
                }

                if (!removeIdList.isEmpty()) {
                    for (Integer skinId : removeIdList) {
                        skinBond.getBondIdSet().remove(skinId);
                    }

                    skinBond.setLevel(0);//重置光环等级
                    skinBond.setUpdateOption();
                }

                //修复羁绊数据,不满足当前皮肤升级要求的,等级减1
                if (skinBond.getLevel() > 0) {
                    CombInfo skinBondCombInfo = SkinMgr.getSkinBondCombInfo(combId);
                    int combSkillId = skinBondCombInfo.getCombSkillId();
                    SkillInfo skillInfo = SkillMgr.getSkillInfo(combSkillId);
                    if (null == skillInfo) {
                        continue;
                    }

                    int upgradeType = skillInfo.getUpgradeType(0);
                    SkillUpgradeInfo skillUpgradeInfo = SkillMgr.getSkillUpgradeInfo(upgradeType, skinBond.getLevel());
                    if (null == skillUpgradeInfo) {
                        continue;
                    }

                    //需要n个皮肤到x级
                    int skinNumNeed = (int) skillUpgradeInfo.getConsumeCount() / 100000;
                    int skinLevelNeed = (int) skillUpgradeInfo.getConsumeCount() % 100000;
                    Map<Integer, Integer> patronsSkinLvMap = new HashMap<>();//key是皮肤id
                    for (Integer skinId : skinBondCombInfo.getCombList()) {
                        if (!skinBond.getBondIdSet().contains(skinId)) {
                            continue;
                        }
                        UserSkin userSkin = getUserSkin(skinId);
                        if (null == userSkin) {
                            continue;
                        }
                        SkinInfo skinInfo = SkinMgr.getSkinInfo(skinId);
                        if (skinInfo == null) {
                            continue;
                        }
                        if (skinInfo.getTwinsId() > 0 && SkinMgr.getSkinInfo(skinInfo.getTwinsId()) != null) {//是双生皮
                            int skinLv = patronsSkinLvMap.getOrDefault(skinInfo.getTwinsId(), 0);
                            skinLv += userSkin.getLevel();
                            patronsSkinLvMap.put(skinInfo.getTwinsId(), skinLv);
                        } else {
                            int skinLv = patronsSkinLvMap.getOrDefault(skinInfo.getSkinId(), 0);
                            skinLv += userSkin.getLevel();
                            patronsSkinLvMap.put(skinInfo.getSkinId(), skinLv);
                        }
                    }

                    for (int skinLv : patronsSkinLvMap.values()) {
                        if (skinLv >= skinLevelNeed) {
                            skinNumNeed--;
                        }
                    }

                    if (skinNumNeed > 0) {//皮肤要求不满足,等级要-1
                        skinBond.setLevel(skinBond.getLevel() - 1);
                        log.info("玩家{},修复门客皮肤羁绊光环等级,光环id={},修复后等级={}", player.getUserId(), combId, skinBond.getLevel());
                    }
                }
            }
        } catch (Exception ex) {
            log.error("门客皮肤羁绊修复错误:" + ex);
        }
        return true;
    }

    @Override
    public void afterLogin() {
        checkSkinResource();
        player.sendPacket(ClientProtocol.U_SKIN_DATA, SkinPb.getUserSkinMsg(userSkinMap.values()));
        player.sendPacket(ClientProtocol.U_LTP_MAIN_ROLE_SKIN_DATA, SkinPb.getUserLTPMainRoleSkinMsg(userLTPMainRoleSkinMap.values()));
        player.sendPacket(ClientProtocol.U_SKIN_PATRONS_BOND_DATA, SkinPb.parseUserPatronsSkinBondListMsg(userPatronsSkinBondMap.values()));
    }

    private void checkSkinResource() {
        if (userSkinMap != null) {
            for (UserSkin skin : userSkinMap.values()) {
                addSkinFlag(skin.getSkinId());
            }
        }
    }

    private void addSkinFlag(int skinId) {
        long getTime = player.getModule(GoodsResourceModule.class).getGoodsFirstGetTime(skinId);
        player.getModule(GoodsResourceModule.class).addResource(skinId, SkinMgr.getLinkType(skinId,getTime));
    }

    @Override
    public boolean saveData() {
        for (UserSkin userSkin : userSkinMap.values()) {
            if (userSkin.isInsertOption()) {
                UserSkinBusiness.addUserSkin(userSkin);
            } else if (userSkin.isUpdateOption()) {
                UserSkinBusiness.updateUserSkin(userSkin);
            }
        }

        for (UserLTPMainRoleSkin userLTPMainRoleSkin : userLTPMainRoleSkinMap.values()) {
            if (userLTPMainRoleSkin.isInsertOption()) {
                UserSkinBusiness.addUserLTPMainRoleSkin(userLTPMainRoleSkin);
            } else if (userLTPMainRoleSkin.isUpdateOption()) {
                UserSkinBusiness.updateUserLTPMainRoleSkin(userLTPMainRoleSkin);
            }
        }

        for (Integer combId : userPatronsSkinBondMap.keySet()) {
            UserPatronsSkinBond skinBond = userPatronsSkinBondMap.get(combId);
            if (null == skinBond) {
                continue;
            }
            if (skinBond.isInsertOption()) {
                new UserPatronsSkinBondDaoImpl().add(skinBond);
            } else if (skinBond.isUpdateOption()) {
                new UserPatronsSkinBondDaoImpl().update(skinBond);
            }
        }
        return true;
    }

    public UserSkin getUserSkin(int skinId) {
        return userSkinMap.get(skinId);
    }

    public void syncSingleSkin(int skinId) {
        UserSkin userSkin = userSkinMap.get(skinId);
        if (userSkin != null) {
            player.sendPacket(ClientProtocol.U_SKIN_SINGLE, SkinPb.getUserSkinEntityMsg(userSkin));
        }
    }

    public void syncSingleLTPMainRoleSkin(int skinId) {
        UserLTPMainRoleSkin userLTPMainRoleSkin = userLTPMainRoleSkinMap.get(skinId);
        if (userLTPMainRoleSkin != null) {
            player.sendPacket(ClientProtocol.U_LTP_MAIN_ROLE_SKIN_SINGLE, SkinPb.getUserLTPMainRoleSkinEntityMsg(userLTPMainRoleSkin));
        }
    }


    /**
     * 获取皮肤加成值
     *
     * @param belongToId
     * @param skinType
     * @param skillType
     * @return
     */
    public BigInteger getSkinAddValue(int belongToId, eSkinType skinType, eSkillType skillType) {
        BigInteger addValue = BigInteger.ZERO;
        for (UserSkin userSkin : userSkinMap.values()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfoMap().get(userSkin.getSkinId());
            if (skinInfo == null) {
//                log.error("skinInfo is null. skinId : {}", userSkin.getSkinId());
                continue;
            }
            if (skinInfo.getType() == eSkinType.MainRole.getValue() ||
                    (skinInfo.getType() == skinType.getValue() && skinInfo.getBelongRole() == belongToId)) {
                for (int skillId : skinInfo.getSkinEffect()) {
                    SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
                    if (skillInfo == null) {
                        log.error("skillInfo is null. skillId : {}", skillId);
                        continue;
                    }
                    if (skillInfo.getType() == skillType.getValue()) {
                        addValue = addValue.add(BigInteger.valueOf(SkillMgr.getSkillAddition(skillInfo, userSkin.getLevel())));
                    }
                }
            }
        }
        return addValue;
    }

    public void useLTPMainRoleSkin(int goodsId) {
        UserLTPMainRoleSkin userLTPMainRoleSkin;
        int skinId = GoodsMgr.getLTPMainRoleSkinGoodId(goodsId);
        SkinInfo skinInfo = SkinMgr.getSkinInfo(skinId);
        if (skinInfo == null) {
            log.error("skinInfo is null. skinId : {}", goodsId);
            return;
        }
        GoodsInfo goodsInfo = GoodsMgr.getGoodsById(goodsId);
        long nowTime = System.currentTimeMillis();
        if (!userLTPMainRoleSkinMap.containsKey(skinId)) {
            userLTPMainRoleSkin = new UserLTPMainRoleSkin();
            userLTPMainRoleSkin.setUserId(player.getUserId());
            userLTPMainRoleSkin.setSkinId(skinId);
            userLTPMainRoleSkin.setAddQualification(goodsInfo.getParamList().get(0).longValue());
            userLTPMainRoleSkin.setOverTime(goodsInfo.getParamList().get(1).longValue() * DateHelper.DAY_MILLIONS + nowTime);
            userLTPMainRoleSkin.setInsertOption();
            userLTPMainRoleSkinMap.put(skinId, userLTPMainRoleSkin);
            player.getModule(PlayerModule.class).changeDecoration(eDecorationType.Costume.getValue(), skinId, false);
            PlayerProto.PlayerDataTempMsg.Builder msg = PlayerPb.parsePlayerDataTempMsg(player.getUserInfo(), player.getModule(AttributeModule.class).getUserAttributeMap());
            if(null != msg) {
                player.sendPacket(Protocol.U_PLAYER_DATA, msg);
            }
        } else {
            userLTPMainRoleSkin = userLTPMainRoleSkinMap.get(skinId);
            userLTPMainRoleSkin.setAddQualification(userLTPMainRoleSkin.getAddQualification() + goodsInfo.getParamList().get(0).longValue());
            long gap = userLTPMainRoleSkin.getOverTime() - nowTime;
            gap = gap > 0 ? gap : 0;
            userLTPMainRoleSkin.setOverTime(goodsInfo.getParamList().get(1).longValue() * DateHelper.DAY_MILLIONS + nowTime + gap);
        }
        syncSingleLTPMainRoleSkin(skinId);

        PatronsModule patronsModule = player.getModule(PatronsModule.class);
        List<UserPatrons> specList = patronsModule.getAddQuaPatronsList(skinInfo.getBelongRole());
        if (specList != null) {
            // 通知对应门客资质变更
            patronsModule.onPatronsListChange(specList);
            patronsModule.syncPatronsDataAll(false);
        } else {
            // 通知单个门客资质变更
            UserPatrons userPatrons = patronsModule.getUserPatrons(skinInfo.getBelongRole());
            if (userPatrons == null) {
                log.info("patrons is null. patronId : {}", skinInfo.getBelongRole());
                return;
            }
            patronsModule.onPatronsChange(userPatrons);
            patronsModule.syncPatronsData(userPatrons);
        }
    }

    /**
     * 使用皮肤道具
     *
     * @param goodsId
     */
    public void useSkin(int goodsId) {
        int skinLevel = 0;
        UserSkin userSkin;
        int piecesGetWay = 0;
        SkinInfo skinInfo = SkinMgr.getSkinInfo(goodsId);
        if (skinInfo == null) {
            log.error("skinInfo is null. skinId : {}", goodsId);
            return;
        }
        //先算一下产出
        if (skinInfo.getType() == eSkinType.ManorObject.getValue()) {
            player.getModule(ManorModule.class).notifySkinAdd(skinInfo);
        }

        if (!userSkinMap.containsKey(goodsId)) {
            // 激活
            userSkin = new UserSkin();
            userSkin.setUserId(player.getUserId());
            userSkin.setSkinId(goodsId);
            userSkin.setLevel(1);
            userSkin.setInsertOption();
            userSkinMap.put(userSkin.getSkinId(), userSkin);
            syncSingleSkin(goodsId);
            skinLevel = userSkin.getLevel();
            addSkinFlag(goodsId);
            piecesGetWay = 1;
        } else {
            // 升级
            userSkin = userSkinMap.get(goodsId);
            userSkin.setLevel(userSkin.getLevel() + 1);
            syncSingleSkin(goodsId);
            skinLevel = userSkin.getLevel();
            piecesGetWay = 2;
        }
        //同步霓裳卷残片数据
        player.getModule(SkinVolumeModule.class).updateSkinGetPiecesCount();
        int pieces = piecesGetWay == 1 ? skinInfo.getUnlockGet() : skinInfo.getUpgradeGet();
        LogMgr.addLogSkinVolumePiecesGet(new LogSkinVolumePiecesGet(getUserId(), goodsId, pieces, piecesGetWay, new Date()));

        if (skinInfo.getType() == eSkinType.Beauty.getValue()) {
            BeautyModule beautyModule = player.getModule(BeautyModule.class);
            UserBeauty userBeauty = beautyModule.getUserBeauty(skinInfo.getBelongRole());
            if (userBeauty == null) {
                log.error("beauty is null. beautyId : {}", skinInfo.getBelongRole());
                return;
            }
            recaclBeautyAttr(userBeauty, true);
            beautyModule.syncUserBeauty(userBeauty);
            //v4.1
            DataAnalyticsMgr.trackBeautySkin(player, userBeauty, userSkin, piecesGetWay, getSkinIdList(eSkinType.Beauty).size());
            //4.2 美女声音同步
            if (piecesGetWay == 1){     //用一下霓裳卷的判断解锁还是升级，解锁判断是否有新语音
                beautyModule.checkBeautyVoice(userBeauty);
                beautyModule.syncBeautyVoice(beautyModule.getUserBeautyVoice(userBeauty));
            }
        } else if (skinInfo.getType() == eSkinType.Patrons.getValue()) {
            PatronsModule patronsModule = player.getModule(PatronsModule.class);
            UserPatrons userPatrons = patronsModule.getUserPatrons(skinInfo.getBelongRole());
            if (userPatrons == null) {
                log.error("patrons is null. patronId : {}", skinInfo.getBelongRole());
                return;
            }

            // 初始化技能及皮肤技能等级增加
            PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(userPatrons.getPatronsId());
            patronsModule.initSkill(userPatrons, patronsInfo);

            // 门客皮肤组合
            checkPatronsSkinCombUnlock(userSkin, skinInfo, true);

            // 通知门客变更
            patronsModule.onPatronsChange(null);
            patronsModule.syncPatronsDataAll(false);


        } else if (skinInfo.getType() == eSkinType.MainRole.getValue()) {
            // 主角时装对所有美女生效
            BeautyModule beautyModule = player.getModule(BeautyModule.class);
            for (UserBeauty userBeauty : beautyModule.getBeautyMap().values()) {
                recaclBeautyAttr(userBeauty, true);
            }
            beautyModule.syncUserBeauty(new ArrayList<>(beautyModule.getBeautyMap().values()), false);
            player.getModule(PatronsModule.class).onPatronsChange(null);
        } else if (skinInfo.getType() == eSkinType.ManorObject.getValue()) {
            long addProsperousValue = 0L;
            if (userSkin.getLevel() == 1) {
                addProsperousValue = skinInfo.getUnlockGet();
                player.getModule(ManorModule.class).autoUseSkin(skinInfo.getBelongRole(), skinInfo.getSkinId());
            } else if (userSkin.getLevel() > 1) {
                addProsperousValue = skinInfo.getUpgradeGet();
            }
            player.getModule(ManorModule.class).addProsperousValue(addProsperousValue, "皮肤解锁升级");
            player.getModule(ManorModule.class).syncManorData();
            LogMgr.addLogManorSkinLvUp(new LogManorSkinLvUp(player.getUserId(), skinInfo.getSkinId(), skinInfo.getBelongRole(), goodsId + "=1", userSkin.getLevel(), new Date()));
        } else if (skinInfo.getType() == eSkinType.EstateSkin.getValue()) {

        }else if (skinInfo.getType() == eSkinType.BankSkin.getValue()) {
            //不知道要干什么
        }
    }

    /**
     * 重新计算魅力及亲密度
     *
     * @param userBeauty
     */
    public void recaclBeautyAttr(UserBeauty userBeauty, boolean isAddLog) {
        int oldIntimacy = userBeauty.getTotalIntimacy();
        int oldGlamour = userBeauty.getTotalGlamour();
        BeautyInfo beautyInfo = BeautyMgr.getBeautyInfo(userBeauty.getBeautyId());
        int embroideryMeter = player.getModule(SkinVolumeModule.class).getSkinVolumeData().getEmbroideryMeter();
        Map<Integer, ManorTechnologyData> technologyDataMap = new ConcurrentHashMap<>();
        ManorTechnologyModel technologyModel = player.getModule(ManorModule.class).getTechnologyModel();
        if (technologyModel != null) {
            technologyDataMap = technologyModel.getTechnologyDataMap();
        }
        Map<Integer, UserAssistantDecoration> userAssistantDecorationMap = new ConcurrentHashMap<>(player.getModule(AssistantSkinModule.class).getAssistantDecorationMap());
        int addIntimacyValue = getSkinAddValue(userBeauty.getBeautyId(), eSkinType.Beauty, eSkillType.SkinAddIntimacy).intValue();
        addIntimacyValue += getSkinAddValue(userBeauty.getBeautyId(), eSkinType.MainRole, eSkillType.SkinAddAllIntimacy).intValue();
        //霓裳秘史加成
        addIntimacyValue += SkinVolumeMgr.getSkillAddition(embroideryMeter, eSkillType.SkinVolumeBeautyIntimacyAddition.getValue(), beautyInfo.getOccupation());
        //庄园亲密度加成
        addIntimacyValue += ManorMgr.getManorAddValue(userBeauty.getBeautyId(), technologyDataMap, eSkillType.ManorBeautyIntimacyAddValue.getValue());
        //酒肆技能亲密值
        addIntimacyValue += WineShopMgr.getWineShopSkillAddValue(player, eSkillType.WineShopOccupationBeautyIntimacyAdd.getValue(), beautyInfo.getOccupation());
        //小助理皮肤增加亲密值
        addIntimacyValue += AssistantSkinMgr.getSkinAddition(userAssistantDecorationMap, eSkillType.SkinVolumeBeautyIntimacyAddition.getValue(), beautyInfo.getOccupation());
        // 晋升技能增加亲密值
        addIntimacyValue += BeautyMgr.getPromotionSkillAddition(userBeauty, eSkillType.BeautyPromotionSkill.getValue(), 1);

        int addGlamourValue = getSkinAddValue(userBeauty.getBeautyId(), eSkinType.Beauty, eSkillType.SkinAddGlamour).intValue();
        addGlamourValue += getSkinAddValue(userBeauty.getBeautyId(), eSkinType.MainRole, eSkillType.SkinAddAllGlamour).intValue();
        //霓裳秘史加成
        addGlamourValue += SkinVolumeMgr.getSkillAddition(embroideryMeter, eSkillType.SkinVolumeBeautyGlamourAddition.getValue(), beautyInfo.getOccupation());
        //庄园魅力值加成
        addGlamourValue += ManorMgr.getManorAddValue(userBeauty.getBeautyId(), technologyDataMap, eSkillType.ManorBeautyGlamourAddValue.getValue());
        //酒肆技能魅力值
        addGlamourValue += WineShopMgr.getWineShopSkillAddValue(player, eSkillType.WineShopOccupationBeautyGlamourAdd.getValue(), beautyInfo.getOccupation());
        //小助理皮肤增加魅力值
        addGlamourValue += AssistantSkinMgr.getSkinAddition(userAssistantDecorationMap, eSkillType.SkinVolumeBeautyGlamourAddition.getValue(), beautyInfo.getOccupation());
        // 晋升技能增加魅力值
        addGlamourValue += BeautyMgr.getPromotionSkillAddition(userBeauty, eSkillType.BeautyPromotionSkill.getValue(), 2);

        userBeauty.setSkinIntimacy(addIntimacyValue);
        userBeauty.setSkinGlamour(addGlamourValue);
        BeautyModule beautyModule = player.getModule(BeautyModule.class);

        //藏品系统-特定职业美女才华增加固定值
        long curioAddGlamour = CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioBeautyGlamourSkill.getValue(), player, beautyInfo.getOccupation());
        curioAddGlamour += CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioBeautyGlamourAdd.getValue(), player, beautyInfo.getBeautyId());
        userBeauty.setCurioGlamour((int) curioAddGlamour);

        long curioAddIntimacy = CurioMgr.getSkillAdditionBySkillType(eSkillType.BeautyIntimacyAddSkill.getValue(), player, beautyInfo.getOccupation());
        curioAddIntimacy += CurioMgr.getSkillAdditionBySkillType(eSkillType.CurioBeautyIntimacyAdd.getValue(), player, beautyInfo.getBeautyId());
        userBeauty.setCurioIntimacy((int) curioAddIntimacy);

        beautyModule.intimacyChange(userBeauty, oldIntimacy, userBeauty.getTotalIntimacy() - oldIntimacy, eLogMoneyType.Skin.getValue(),
                eLogMoneyType.SkinUpgrade.getValue(), isAddLog);
        beautyModule.glamourChange(userBeauty, oldGlamour, userBeauty.getTotalGlamour() - oldGlamour, eLogMoneyType.Skin.getValue(),
                eLogMoneyType.SkinUpgrade.getValue(), isAddLog);
    }

    /**
     * 获取指定门客所有皮肤技能列表
     *
     * @param patronsId
     * @return
     */
    public Map<Integer, Integer> getPatronsSkillMap(int patronsId) {
        Map<Integer, Integer> skillMap = new HashMap<>();
        for (UserSkin userSkin : userSkinMap.values()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
            if (skinInfo == null) {
                log.error("skinInfo is null. skinId : {}", userSkin.getSkinId());
                continue;
            }
            if (skinInfo.getType() == eSkinType.Patrons.getValue() && skinInfo.getBelongRole() == patronsId) {
                for (int skillId : skinInfo.getSkinEffect()) {
                    int skinLv = 0;
                    if(skillMap.containsKey(skillId)){
                        skinLv = skillMap.get(skillId);
                    }
                    skinLv += userSkin.getLevel();
                    skillMap.put(skillId, skinLv);
                }

            }
        }
        return skillMap;
    }

    /**
     * 皮肤是否已经拥有
     *
     * @param skinId
     * @return
     */
    public boolean isSkinExist(int skinId) {
        UserSkin userSkin = getUserSkinMap().get(skinId);
        if (userSkin == null) {
            return false;
        }
        return true;
    }

    /**
     * 门客皮肤组合解锁
     *
     * @param userSkin
     * @param skinInfo
     * @param isSendMsg
     */
    private void checkPatronsSkinCombUnlock(UserSkin userSkin, SkinInfo skinInfo, boolean isSendMsg) {
        if (skinInfo == null) {
            return;
        }
        List<UserPatrons> syncList = new ArrayList<>();
        CombInfo patronsSkinComb = SkinMgr.getPatronsSkinComb(skinInfo.getCombId());
        if (null == patronsSkinComb) {
            return;
        }
        //组合组合皮肤了(可以多个组合合并一个共同升级一个技能)
        List<Integer> combCombObjectIdList = SkinMgr.getCombCombObjectIdList(skinInfo.getCombId());
        int combPatronsSkinCount = 0;
        for (int skinId : combCombObjectIdList) {
            if (isSkinExist(skinId)) {
                combPatronsSkinCount++;
            }
        }
        PatronsModule patronsModule = player.getModule(PatronsModule.class);
        if (patronsSkinComb.getCombSkillId() > 0) {//有些组合门客就一个技能，不需要加
            UserPatrons userPatrons = patronsModule.getUserPatrons(skinInfo.getBelongRole());
            if (null != userPatrons) {
                UserPatronsSkill combSkill = userPatrons.getPatronsSkill(ePatronsSkillType.PatronsSkinComb.getValue(), patronsSkinComb.getCombSkillId());
                if (null == combSkill) {
                    combSkill = PatronsMgr.initUserPatronsSkill(userPatrons, patronsSkinComb.getCombSkillId(), ePatronsSkillType.PatronsSkinComb.getValue(),
                            combPatronsSkinCount,0);
                    patronsModule.addPatronsSkill(userPatrons,combSkill);
                    syncList.add(userPatrons);
                } else {
                    if (combSkill.getSkillLv() != combPatronsSkinCount) {
                        combSkill.setSkillLv(combPatronsSkinCount);
                        syncList.add(userPatrons);
                    }
                }
            }
        }
        for (int skinId : combCombObjectIdList) {
            SkinInfo tempSkin = SkinMgr.getSkinInfo(skinId);
            UserPatrons patrons = patronsModule.getUserPatrons(tempSkin.getBelongRole());
            if (null != patrons) {
                CombInfo combPatronsSkinComb = SkinMgr.getPatronsSkinComb(tempSkin.getCombId());
                UserPatronsSkill hasSkill = patrons.getPatronsSkill(ePatronsSkillType.PatronsSkinComb.getValue(), combPatronsSkinComb.getCombSkillId());
                if (null != hasSkill && hasSkill.getSkillLv() != combPatronsSkinCount) {
                    hasSkill.setSkillLv(combPatronsSkinCount);
                    if (!syncList.contains(patrons)) {
                        syncList.add(patrons);
                    }
                }
            }
        }
        if (SkinMgr.isUnlockPatronsSkinComb(userSkin.getSkinId(), userSkinMap)) {//解锁组合
            for (int skinId : patronsSkinComb.getObjectIdList()) {
                SkinInfo tempSkinInfo = SkinMgr.getSkinInfo(skinId);
                if (null == tempSkinInfo) {
                    continue;
                }
                UserPatrons patrons = patronsModule.getUserPatrons(tempSkinInfo.getBelongRole());
                if (null == patrons) {
                    continue;
                }
                UserPatronsSkill hasSkill = patrons.getPatronsSkill(ePatronsSkillType.PatronsSkinComb.getValue(), patronsSkinComb.getSkillId(skinId));
                if (null == hasSkill) {
                    UserPatronsSkill patronsSkill = PatronsMgr.initUserPatronsSkill(patrons, patronsSkinComb.getSkillId(skinId), ePatronsSkillType.PatronsSkinComb.getValue(), 1,0);
                    patronsModule.addPatronsSkill(patrons,patronsSkill);
                    if (!syncList.contains(patrons)) {
                        syncList.add(patrons);
                    }
                }
            }
        } else {
            for (int skinId : patronsSkinComb.getObjectIdList()) {
                SkinInfo tempSkinInfo = SkinMgr.getSkinInfo(skinId);
                if (null == tempSkinInfo) {
                    continue;
                }
                UserPatrons patrons = patronsModule.getUserPatrons(tempSkinInfo.getBelongRole());
                if (null == patrons) {
                    continue;
                }
                if (!syncList.contains(patrons)) {
                    syncList.add(patrons);
                }
            }
        }
        if (syncList.size() > 0) {
            patronsModule.onPatronsListChange(syncList);
            if (isSendMsg) {
                patronsModule.syncPatronsData(syncList, false);
            }
        }
    }

    /**
     * 获取主角皮肤集合
     *
     * @return
     */
    public List<Integer> getMainRoleSkinIdList() {
        List<Integer> dataList = new ArrayList<>();
        for (UserSkin userSkin : userSkinMap.values()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
            if (skinInfo == null) {
                log.error("getCostumeSkinIdList skin info no find,id:{}", userSkin.getSkinId());
                continue;
            }
            if (skinInfo.getType() == eSkinType.MainRole.getValue()) {
                dataList.add(userSkin.getSkinId());
            }
        }
        return dataList;
    }

    public List<Integer> getLTPMainRoleSkinIdList() {
        List<Integer> dataList = new ArrayList<>();
        for (UserLTPMainRoleSkin userSkin : userLTPMainRoleSkinMap.values()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
            if (skinInfo == null) {
                log.error("getCostumeSkinIdList skin info no find,id:{}", userSkin.getSkinId());
                continue;
            }
            long nowTime = System.currentTimeMillis();
            if (skinInfo.getType() == eSkinType.LTPMainRole.getValue() && userSkin.getOverTime() > nowTime) {
                dataList.add(skinInfo.getSkinId());
            }
        }
        return dataList;
    }

    /**
     * 获取美女门客皮肤集合
     *
     * @return
     */
    public List<UserSkin> getSkinList() {
        List<UserSkin> userSkins = new ArrayList<>();
        for (UserSkin userSkin : userSkinMap.values()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
            if (skinInfo != null && (skinInfo.getType() == eSkinType.Patrons.getValue()
                    || skinInfo.getType() == eSkinType.Beauty.getValue())) {
                userSkins.add(userSkin);
            }
        }
        return userSkins;
    }

    /**
     * 获取门客皮肤集合
     *
     * @return
     */
    public List<UserSkin> getPatronsSkinList() {
        List<UserSkin> userSkins = new ArrayList<>();
        for (UserSkin userSkin : userSkinMap.values()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
            if (skinInfo != null && skinInfo.getType() == eSkinType.Patrons.getValue()) {
                userSkins.add(userSkin);
            }
        }
        return userSkins;
    }

    /**
     * 获取美女拥有的皮肤
     */
    public List<Integer> getSkinListByBeautyId(int beautyId) {
        List<Integer> list = new ArrayList<>();
        for (Integer id : userSkinMap.keySet()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(id);
            if (skinInfo != null && (skinInfo.getType() == eSkinType.Beauty.getValue() && skinInfo.getBelongRole() == beautyId)) {
                list.add(id);
            }
        }
        return list;
    }

    public List<UserSkin> getUserSkinListByBeautyId(int beautyId) {
        List<UserSkin> list = new ArrayList<>();
        for (UserSkin userSkin : userSkinMap.values()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
            if (skinInfo != null && (skinInfo.getType() == eSkinType.Beauty.getValue() && skinInfo.getBelongRole() == beautyId)) {
                list.add(userSkin);
            }
        }
        return list;
    }

//    /**
//     * 获得拥有的美女皮肤的无双级能升级用的转换值
//     *
//     * @param beautyId
//     * @return
//     */
//    public int getBeautyPeerlessSkillUpSkinNumHave(int beautyId) {
//        int numHave = 0;
//        List<Integer> attrList = StringUtils.stringToIntegerList(GameConfig.BEAUTY_PEERLESS_PATRONS_SKILL_SKINS_CHANGE, "\\|");
//        for (UserSkin userSkin : userSkinMap.values()) {
//            SkinInfo skinInfo = SkinMgr.getSkinInfo(userSkin.getSkinId());
//            if (skinInfo != null && (skinInfo.getType() == eSkinType.Beauty.getValue() && skinInfo.getBelongRole() == beautyId)) {
//                if (skinInfo.isPeerless() == 1) {
//                    //取参数0
//                    if (attrList.size() >= 1) {
//                        numHave += Math.min(userSkin.getLevel(), attrList.get(0));
//                    }
//                } else{
//                    if (attrList.size() >= skinInfo.getQuality() + 1) {
//                        numHave += Math.min(userSkin.getLevel(), attrList.get(skinInfo.getQuality()));
//                    }
//                }
//            }
//        }
//
//        return numHave;
//    }

    public List<Integer> getHeadIconIdList() {
        List<Integer> list = new ArrayList<>();
        for (Integer id : userSkinMap.keySet()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(id);
            if (skinInfo != null && (skinInfo.getType() == eSkinType.Patrons.getValue() || skinInfo.getType() == eSkinType.Beauty.getValue()
                    || skinInfo.getType() == eSkinType.MainRole.getValue())) {
                list.add(id);
            }
        }
        return list;
    }

    /**
     * 通过门客id获取其皮肤列表
     */
    public List<Integer> getPatronsSkinIdList(int patronsId) {
        List<Integer> hasSkinList = new ArrayList<>();
        for (int hasSkinId : userSkinMap.keySet()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(hasSkinId);
            if (skinInfo == null) {
                continue;
            }
            if (SkinMgr.getSkinInfo(hasSkinId).getBelongRole() == patronsId && SkinMgr.getSkinInfo(hasSkinId).getType() == eSkinType.Patrons.getValue()) {
                hasSkinList.add(hasSkinId);
            }
        }
        return hasSkinList;
    }

    /**
     * 获取一个类型拥有所有皮肤id
     */
    public List<Integer> getSkinIdList(eSkinType type) {
        List<Integer> hasSkinList = new ArrayList<>();
        for (int hasSkinId : userSkinMap.keySet()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(hasSkinId);
            if (skinInfo == null) {
                continue;
            }
            if (skinInfo.getType() == type.getValue()) {
                hasSkinList.add(hasSkinId);
            }
        }
        return hasSkinList;
    }

    public UserPatronsSkinBond getUserPatronsSkinBond(int combId) {
        return userPatronsSkinBondMap.get(combId);
    }

    public Map<Integer, UserPatronsSkinBond> getUserPatronsSkinBondMap() {
        return userPatronsSkinBondMap;
    }

    /**
     * 激活皮肤羁绊
     *
     * @param skinIdList
     * @return
     */
    public int activePatronsSkinBond(int combId, List<Integer> skinIdList) {
        if (skinIdList.isEmpty()) {
            return GameErrorCode.E_ERROR_DATA;
        }
        CombInfo skinBondCombInfo = SkinMgr.getSkinBondCombInfo(combId);
        if (null == skinBondCombInfo) {
            return GameErrorCode.E_PATRONS_COMBID_ERROR;
        }

        UserPatronsSkinBond userPatronsSkinBond = userPatronsSkinBondMap.get(combId);
        if (null == userPatronsSkinBond) {
            userPatronsSkinBond = new UserPatronsSkinBond();
            userPatronsSkinBond.setUserId(player.getUserId());
            userPatronsSkinBond.setCombId(combId);
            userPatronsSkinBond.setLevel(0);
            userPatronsSkinBond.setBondIdSet(new ConcurrentHashSet());
            userPatronsSkinBond.setInsertOption();
            userPatronsSkinBondMap.put(combId, userPatronsSkinBond);
        }

        for (Integer skinId : skinIdList) {
            if (!skinBondCombInfo.getCombList().contains(skinId)) {
                return GameErrorCode.E_SKIN_NOT_EXIST;
            }
            UserSkin userSkin = getUserSkin(skinId);
            if (null == userSkin) {
                return GameErrorCode.E_SKIN_NOT_EXIST;
            }

            if (userPatronsSkinBond.getBondIdSet().contains(skinId)) {
                return GameErrorCode.E_SKIN_BOND_ACTIVED;
            }

            userPatronsSkinBond.addBondId(skinId);
        }

        //更新门客资质/更新赚钱
        onSkinBondCombPatronsChange(userPatronsSkinBond);

        //日志

        SkinProto.UserPatronsSkinBondActiveRespMsg.Builder builder = SkinProto.UserPatronsSkinBondActiveRespMsg.newBuilder();
        builder.setRet(0);
        builder.setSkinBondInfo(SkinPb.parseUserPatronsSkinBondMsg(userPatronsSkinBond));
        player.sendPacket(ClientProtocol.U_SKIN_PATRONS_BOND_ACTIVE, builder);

        return 0;
    }

    /**
     * 升级皮肤羁绊光环等级
     *
     * @param combId
     * @return
     */
    public int upgradePatronsSkinBondCombLevel(int combId) {
        CombInfo skinBondCombInfo = SkinMgr.getSkinBondCombInfo(combId);
        if (null == skinBondCombInfo) {
            return GameErrorCode.E_PATRONS_COMBID_ERROR;
        }
        UserPatronsSkinBond userPatronsSkinBond = getUserPatronsSkinBond(combId);
        if (null == userPatronsSkinBond) {
            return GameErrorCode.E_SKIN_BOND_COMB_NOT_ACTIVED;
        }

        int combSkillId = skinBondCombInfo.getCombSkillId();
        SkillInfo skillInfo = SkillMgr.getSkillInfo(combSkillId);
        if (null == skillInfo) {
            return GameErrorCode.E_SKIN_BOND_COMB_SKILL_NOT_FOUND;
        }
        if (userPatronsSkinBond.getLevel() >= skillInfo.getMaxLevel()) {
            return GameErrorCode.E_SKIN_BOND_COMB_SKILL_LEVEL_MAX;
        }

        int upgradeType = skillInfo.getUpgradeType(0);
        SkillUpgradeInfo skillUpgradeInfo = SkillMgr.getSkillUpgradeInfo(upgradeType, userPatronsSkinBond.getLevel() + 1);
        if (null == skillUpgradeInfo) {
            return GameErrorCode.E_SKIN_BOND_COMB_SKILL_LEVEL_MAX;
        }

        //需要n个皮肤到x级
        int skinNumNeed = (int) skillUpgradeInfo.getConsumeCount() / 100000;
        int skinLevelNeed = (int) skillUpgradeInfo.getConsumeCount() % 100000;
        //从合并同个门客皮肤改成合并双生皮皮肤
        Map<Integer, Integer> patronsSkinLvMap = new HashMap<>();//key改成皮肤id
        for (Integer skinId : skinBondCombInfo.getCombList()) {
            if (!userPatronsSkinBond.getBondIdSet().contains(skinId)) {
                continue;
            }
            UserSkin userSkin = getUserSkin(skinId);
            if (null == userSkin) {
                continue;
            }
            SkinInfo skinInfo = SkinMgr.getSkinInfo(skinId);
            if (skinInfo == null) {
                continue;
            }
            if (skinInfo.getTwinsId() > 0 && SkinMgr.getSkinInfo(skinInfo.getTwinsId()) != null) {//是双生皮
                int skinLv = patronsSkinLvMap.getOrDefault(skinInfo.getTwinsId(), 0);
                skinLv += userSkin.getLevel();
                patronsSkinLvMap.put(skinInfo.getTwinsId(), skinLv);
            } else {
                int skinLv = patronsSkinLvMap.getOrDefault(skinInfo.getSkinId(), 0);
                skinLv += userSkin.getLevel();
                patronsSkinLvMap.put(skinInfo.getSkinId(), skinLv);
            }
        }

        for (int skinLv : patronsSkinLvMap.values()) {
            if (skinLv >= skinLevelNeed) {
                skinNumNeed--;
            }
        }

        if (skinNumNeed > 0) {
            return GameErrorCode.E_SKIN_BOND_COMB_SKILL_LEVEL_UP_NOT_ENOUGH;
        }

        userPatronsSkinBond.setLevel(userPatronsSkinBond.getLevel() + 1);

        onSkinBondCombPatronsChange(userPatronsSkinBond);

        SkinProto.UserPatronsSkinBondCombUpgradeRespMsg.Builder builder = SkinProto.UserPatronsSkinBondCombUpgradeRespMsg.newBuilder();
        builder.setRet(0);
        builder.setSkinBondInfo(SkinPb.parseUserPatronsSkinBondMsg(userPatronsSkinBond));
        player.sendPacket(ClientProtocol.U_SKIN_PATRONS_BOND_COMB_UPGRADE, builder);

        return 0;
    }

    /**
     * 皮肤羁绊门客数据变化
     *
     * @param userPatronsSkinBond
     */
    public void onSkinBondCombPatronsChange(UserPatronsSkinBond userPatronsSkinBond) {
        if (null == userPatronsSkinBond) {
            return;
        }
        List<UserPatrons> userPatronsList = new ArrayList<>();
        for (Integer skinId : userPatronsSkinBond.getBondIdSet()) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(skinId);
            if (null == skinInfo) {
                continue;
            }
            int patronsId = skinInfo.getBelongRole();
            UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(patronsId);
            if (null == userPatrons) {
                continue;
            }
            if (!userPatronsList.contains(userPatrons)) {
                userPatronsList.add(userPatrons);
            }
        }
        if (!userPatronsList.isEmpty()) {
            player.getModule(PatronsModule.class).onPatronsListChange(userPatronsList);
        }

    }

    public void openSpecialSkinBox(int goodsId, long num, eLogMoneyType master, eLogMoneyType son) {
        List<GoodsBagInfo> goodsBagInfoList =  CommonMgr.getGoodsBagInfoList(goodsId);
        BeautyModule beautyModule = player.getModule(BeautyModule.class);
        Property reward = new Property();
        //养禅女皮肤
        int defaultSkinId = 0;
        for (GoodsBagInfo goodsBagInfo : goodsBagInfoList) {
            SkinInfo skinInfo = SkinMgr.getSkinInfo(goodsBagInfo.getGoodsId());
            if(skinInfo == null){
                continue;
            }
            if(skinInfo.getBelongRole() == GameConfig.BEAUTY_ID_SILKWORM){
                defaultSkinId = skinInfo.getSkinId();
            }
            UserBeauty userBeauty = beautyModule.getUserBeauty(skinInfo.getBelongRole());
            if(userBeauty == null){
                continue;
            }
            reward.addProperty(goodsBagInfo.getGoodsId(), BigInteger.valueOf(num));
        }
        if(reward.isNothing() && defaultSkinId > 0){
            reward.addProperty(defaultSkinId, BigInteger.valueOf(num));
            SkinMgr.getLogger().info("player {} get {} num {}, default ", player.getUserId(), defaultSkinId, num);
        }
        if(!reward.isNothing() && reward.getCountByGoodsId(goodsId).compareTo(BigInteger.ZERO) == 0){
            player.getModule(CurrencyModule.class).addCurrency(reward, master, son);
        }else {
            SkinMgr.getLogger().info("player {} get {} empty", player.getUserId(), goodsId);
        }
    }
}
